//
//  GQJLockController.m
//  TotalDemo
//
//  Created by gujian on 16/7/28.
//  Copyright © 2016年 gujian. All rights reserved.
//

#import "GQJLockController.h"
#import "TestRumtime.h"
#import "TestProtocol.h"
#import <pthread/pthread.h>
#import <objc/message.h>

#import <CoreMotion/CoreMotion.h>

OBJC_EXTERN int _objc_rootRetainCount(id);
OBJC_EXTERN void _objc_autoreleasePoolPrint();

typedef void(^TestBlock)(void);

@interface GQJLockController()<TestProtocol>

@property (nonatomic, strong) NSString *str;
@property (nonatomic, assign) NSInteger count;
@property (nonatomic, strong) TestBlock block;

@property (nonatomic) dispatch_queue_t alterQueue;

@end

@implementation GQJLockController
{
    pthread_mutex_t _mutex;         //互斥锁
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    

    _str = [NSString stringWithFormat:@"初始值"];
    
    _alterQueue = dispatch_queue_create("com.alterQueue.com", DISPATCH_QUEUE_CONCURRENT);
    
//    [self concurrentThread];
    
//    objc_msgSend(self,@selector(currentGroupBlock));
    
//    objc_msgSend(self, @selector(testWeakStrongPro));
    [self setTarget];

}


- (void)initMutex
{
    pthread_mutex_init(&_mutex, NULL);
}


- (void)dealloc
{
    pthread_mutex_destroy(&_mutex);
    NSLog(@"%sdealloc",__func__);
}

- (void)concurrentThread
{
    //
    
    __weak typeof(self) weakSelf = self;
    
    dispatch_async(_alterQueue, ^{
//        [weakSelf alterWith:@"修改值1"];
        
        for (int i = 0; i < 10; i++) {
            [weakSelf alterWithValue:i];
        }
        
        
    });
    
    dispatch_async(_alterQueue, ^{
       
//        [weakSelf alterWith:@"修改值2"];
        
        for (int i = 0; i < 10; i++) {
            [weakSelf alterWithValue:i];
        }
        
    });
    
    
}

- (void)alterWith:(NSString *)str
{
    NSThread *current = [NSThread currentThread];
    
    _str = str;
    
    NSLog(@"%@%@",current,_str);
    
}

- (void)alterWithValue:(NSInteger)num
{
    NSThread *current = [NSThread currentThread];
    
    //定义障碍避免脏数据
    dispatch_barrier_async(_alterQueue, ^{
        NSInteger count = _count;
        [NSThread sleepForTimeInterval:0.002];
        _count = count+1;
        
         NSLog(@"修改之后%@%@",current, @(_count));
    });
    

}


- (void)currentGroupBlock
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    
    __block NSInteger result = 0;
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"blk0");
    });
    dispatch_group_async(group, queue, ^{
        result = 1;
        NSLog(@"blk1");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"blk2");
    });
    
//   dispatch_group_notify(group, queue, ^{
//       NSLog(@"done");
//   });
    
    dispatch_time_t timeOut = dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC);
    dispatch_group_wait(group, timeOut);
    if (result == 1) {
        NSLog(@"修改成功");
    }else
    {
        NSLog(@"未修改");
    }
}

//获取绝对时间
dispatch_time_t getAbsoluteTime(NSDate *date)
{
    NSTimeInterval interval;
    double second, subSecond;
    struct timespec time;
    dispatch_time_t milestone;
    
    interval = [date timeIntervalSince1970];
    //modf 分解interval获取interval的整数和小数部分
    subSecond = modf(interval, &second);
    time.tv_sec = second;
    time.tv_nsec = subSecond;
    
    milestone = dispatch_walltime(&time, 0);
    
    return milestone;
}

- (void)testWeakStrongPro
{
    TestRumtime *testRuntime = [[TestRumtime alloc] init];
    
//    NSLog(@"1retainCount:%d",_objc_rootRetainCount(testRuntime));

    NSLog(@"1testRunTimeCount:%d",_objc_rootRetainCount(testRuntime));
    
    void (^CountBlock)() = ^{
    
        [testRuntime testRuntime];
        NSLog(@"testRunTimeCount:%d",_objc_rootRetainCount(testRuntime));
        NSLog(@"self.str:%@",self.str);
        NSLog(@"self.retainCount:%d",_objc_rootRetainCount(self));
    };
    
    
    CountBlock();
    
    
}

- (void)setTarget
{

    //1.改变队列的执行优先级
    //When no quality of service class is specified, the target queue of a newly
    // created dispatch queue is the default priority global concurrent queue.
    dispatch_queue_t serialQueue = dispatch_queue_create("com.gujian.test1", NULL);
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_set_target_queue(serialQueue, globalQueue);
    
    //2.修改用户队列的目标队列，使多个serial queue在目标queue上一次只有一个执行
    
    //2.1使用dispatch_set_target_queue()实现队列的动态调度管理
    //2.2执行dispatch_set_target_queue(queue1, queue2)后queue1和queue2将使用同一个线程
    //及多个队列中的任务同步执行，即一个一个的执行
    //不同任务在同一个串行线程运行http://www.voidcn.com/blog/jeffasd/article/p-6100786.html
    dispatch_queue_t queue1 = dispatch_queue_create("com.gujian.test2", NULL);
    dispatch_queue_t queue2 = dispatch_queue_create("com.gujian.test3", NULL);
    
    dispatch_set_target_queue(queue1, queue2);
    
//    dispatch_async(queue1, ^{
//       
//        for (NSInteger i = 0; i < 10; i++) {
//            NSLog(@"queue1:%@, %ld", [NSThread currentThread], i);
//            [NSThread sleepForTimeInterval:0.5];
//            if (i == 5) {
//                dispatch_suspend(queue2);
////                break;
//            }
//
//        }
//        
//    });
    
    dispatch_async(queue1, ^{
        for (NSInteger i = 0; i < 500; i++) {
            NSLog(@"queue1:%@, %ld",[NSThread currentThread], i);
        }
    });
    
//     dispatch_suspend(queue2);
    
    dispatch_async(queue2, ^{
    
        for (NSInteger i = 0; i < 1000; i++) {
            NSLog(@"queue2:%@, %ld", [NSThread currentThread], i);
        }
        
    });
    
    
    
}


#pragma mark TestProtocol

- (void)testProtocolLogRequired
{
    NSLog(@"implement the method");
}

@end




















